package id.co.rho.scoring.cid.server.dao.impl;

import id.co.rho.scoring.cid.server.dao.GenericDao;
import id.co.rho.scoring.cid.server.util.ServerUtil;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.Parameter;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

@Component
public class GenericDaoImpl implements GenericDao {
    @PersistenceContext
    EntityManager entityManager;

    @Override
    public <T> List<T> getList(String query, boolean isNamedQuery, Map parameters) {
        Query q = null;
        if (!isNamedQuery) {
            q = entityManager.createQuery(query);
        } else {
            q = entityManager.createNamedQuery(query);
        }

        for (Parameter p : q.getParameters()) {
            q.setParameter(p.getName(), parameters.get(p.getName()));
        }
        return q.getResultList();
    }

    @Override
    public <T> T find(Class<T> entityType, Serializable id) {
        return entityManager.find(entityType, id);
    }

    @Override
    @Transactional
    public <T> T merge(T t) {
        return entityManager.merge(t);
    }

    @Override
    public void persist(Object o) {
        entityManager.persist(o);
    }

    @Override
    public <T> T saveOrUpdate(T instance) {
        if(ServerUtil.isTransientEntity(instance)) {
            entityManager.persist(instance);
            return instance;
        }
        return entityManager.merge(instance);
    }

	@Override
	public void remove(Object instance) {
		entityManager.remove(instance);
	}
	
	@Override
	public int executeUpdate(String query, Map parameters){
		Query q = entityManager.createQuery(query);
		
		for (Parameter p : q.getParameters()) {
            q.setParameter(p.getName(), parameters.get(p.getName()));
        }
		return q.executeUpdate();
	}
}
